package org.example.util;


import java.text.DecimalFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 说明: 字符串处理类
 * Created on 2020/4/19 14:51
 *
 * @author tiancheng <276013558@qq.com>
 */
public class StringUtil {
    private final static Pattern P1 = Pattern.compile("\\s*|\t|\r|\n");
    private final static Pattern P2 = Pattern.compile("<[^<]*>|</[^>]*>");

    private StringUtil() {
        throw new UnsupportedOperationException("该类不允许被实例化!");
    }

    private static final char[] DIGITS
            = {
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
            'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
    };

    //构造方法的字符格式这里如果小数不足2位,会以0补足.
    static final DecimalFormat decimalFormat = new DecimalFormat("0.0");

    public static String formatf(float f) {
        return decimalFormat.format(f);
    }


    /**
     * 判断字符串是否为空.
     * <p>
     * 如果字符串不等于null, 则先去除首尾空格后再进行判定.
     * 这里只是简单的使用了java.lang.String提供的trim()方法去除半角空格, 如果字符串含有全角空格, 或二者皆有,
     * 可以使用StringUtil.trim(String)去除首尾空格.
     *
     * @param source 指定的字符串
     * @return 如果为空则返回true, 反之返回false.
     * @see #trim(String)
     */
    public static boolean isEmpty(String source) {
        return null == source || "".equals(source.trim());
    }

    /**
     * 判断字符串是否不为空.
     * <p>
     * 如果字符串不等于null, 则先去除首尾空格后再进行判定.
     * 这里只是简单的使用了java.lang.String提供的trim()方法去除半角空格, 如果字符串含有全角空格, 或二者皆有,
     * 可以使用StringUtil.trim(String)去除首尾空格.
     *
     * @param source 指定的字符串
     * @return 如果不为空则返回true, 反之返回false.
     * @see #trim(String)
     */
    public static boolean isNotEmpty(String source) {
        return !isEmpty(source);
    }


    /**
     * 获取字符串的长度.
     * <p>
     * 本方法与java.lang.String提供的length()的区别在于: 它以字节数来确定字符串的长度.<br>
     * 例如: 单个英文字母或数字的长度=1，单个汉字的长度>=2(取决于系统字符集编码).
     *
     * @param source 指定的字符串
     * @return 字符串的长度
     * @throws NullPointerException 如果source为null
     */
    public static int length(String source) {
        if (null == source) {
            throw new NullPointerException("source");
        }

        int count = 0;
        if (source.length() > 0) {
            char[] temp = source.toCharArray();
            for (char c : temp) {
                count += String.valueOf(c).getBytes().length;
            }
        }

        return count;
    }

    /**
     * 获取字符串的长度.
     * <p>
     * 本方法与StringUtils.length()一样以字节数来确定字符串的长度, 区别在于: 前者完全以统计字节数来获取长度,
     * 后者将所有非单字节字符以指定的字节数来进行统计, 以屏蔽不同系统字符集的编码差异.<br>
     * 例如: 单个英文字母或数字的长度=1，单个汉字的长度<b>始终</b>=3 <i>(bytes=3)</i>.
     *
     * @param source 指定的字符串
     * @param bytes  设置所有非单字节字符的默认字节数.
     * @return 字符串的长度
     * @throws NullPointerException     如果source为null
     * @throws IllegalArgumentException 如果bytes小于1
     */
    public static int length(String source, int bytes) {
        if (null == source) {
            throw new NullPointerException("source");
        }
        if (bytes < 1) {
            throw new IllegalArgumentException("bytes必须大于0! bytes: " + bytes);
        }

        int count = 0;
        if (source.length() > 0) {
            int length;
            char[] temp = source.toCharArray();
            for (char c : temp) {
                length = String.valueOf(c).getBytes().length;
                if (length > 1) {
                    count += bytes;
                } else {
                    count += length;
                }
            }
        }

        return count;
    }

    /**
     * 将字符串解析为int类型.
     * <p>
     * 如果转换失败, 返回指定的默认值(defaultVal)
     *
     * @param source     源字符
     * @param defaultVal 默认值
     * @return 转换后的数字
     * @throws NullPointerException 如果source为null
     */
    public static int parseInt(String source, int defaultVal) {
        if (null == source) {
            throw new NullPointerException("source");
        }

        source = trim(takeOutInvisible(source));

        int result;
        try {
            result = Integer.parseInt(source);
        } catch (NumberFormatException e) {
            result = defaultVal;
        }

        return result;
    }


    /**
     * 去掉字符串中的不可见字符
     *
     * @param source
     * @return
     */
    public static String takeOutInvisible(String source) {
        if (null == source || "".equals(source)) {
            return source;
        }

        Matcher m = P1.matcher(source);
        return m.replaceAll("");
    }

    /**
     * 去除字符串首尾的空格, 包括全角空格.
     *
     * @param source 指定的字符串
     * @return 去除首尾空格后的字符串
     */
    public static String trim(String source) {
        if (null == source || "".equals(source)) {
            return source;
        }

        // 发现对于某些XML中的空格不能正确剔除, 故先trim一次.
        source = source.trim();
        boolean hasStart = true, hasEnd = true;
        // System.out.println("显示原始字符串: '" + source + "' \n");
        for (int i = 1; i <= source.length(); i++) {
            if (hasStart && source.length() > 0) {
                char start = source.charAt(0);
                // System.out.println("start = '" + start + "'");
                if (start == ' ' || start == '　') {
                    source = source.substring(1, source.length());
                    // System.out.println("去除头部空格后: '" + source + "'");
                } else {
                    hasStart = false;
                }
            }

            if (hasEnd && source.length() > 1) {
                char end = source.charAt(source.length() - 1);
                // System.out.println("end = '" + end + "'");
                if (end == ' ' || end == '　') {
                    source = source.substring(0, source.length() - 1);
                    // System.out.println("去除尾部空格后: '" + source + "'");
                } else {
                    hasEnd = false;
                }
            }

            // System.out.println("第" + i + "次迭代后 = '" + source + "'\n");
            if (!hasStart && !hasEnd) {
                break;
            }
        }

        return source;
    }

    /**
     * "1,2,3,4,5,6"以key分隔的数组转化为整形List
     *
     * @param ids
     * @return
     */
    public static List<Integer> convertIdsToIntList(String ids, String key) {
        List<Integer> list = new ArrayList<>();
        if (ids == null || ids.length() == 0)
            return list;

        String[] ps = ids.split(key);
        for (int i = 0; i < ps.length; i++) {
            int id = StringUtil.parseInt(ps[i], -1);
            if (id == -1) {
                continue;
            }

            list.add(id);
        }
        return list;
    }


}
